enum Ordinals {
    First,
    Second,
    Third,
    Fourth,
    Fifth,
}

impl Ordinals {
    /// Returns `true` if the ordinals is [`Fourth`].
    ///
    /// [`Fourth`]: Ordinals::Fourth
    #[must_use]
    fn is_fourth(&self) -> bool {
        matches!(self, Self::Fourth)
    }
}

impl Default for Ordinals {
    fn default() -> Self {
        Self::Third
    }
}

fn main() {
    println!("match 与 go 的 switch 相同,只匹配 enum, 且要求所有分支均匹配到.");

    let ord = Ordinals::First;
    let o = match ord {
        Ordinals::First => "first",
        Ordinals::Second => "second",
        Ordinals::Third => "third",
        Ordinals::Fourth => "fourth",
        Ordinals::Fifth => "fifth",
    };
    println!("{}", o);

    // 只匹配部分,其他用 _ 替代
    let o2 = match ord {
        Ordinals::First => "first",
        _ => "others",
    };
    println!("{}", o2);

    // option 匹配
    let opt = Some("abc");
    match opt {
        Some(x) => println!("{}", x),
        None => println!("none"),
    };

    let opt: Option<i32> = None;
    let res = match_option(opt);
    println!("{}", res);

    let opt: Option<i32> = Some(1);
    if let Some(x) = opt {
        // 是 Some 而非 None 时打印输出
        println!("{}", x);
    }

    let first = Ordinals::Fifth;
    let second = Ordinals::Second;
    let four = Ordinals::Fourth;
    // 没有 let 会报错
    // 用 == 则提示无法对 Ordinals 类型进行比较
    // 可以理解为 if let 就是为了比较 enum 类型的某一个值的语法糖
    if let Ordinals::First = first {
        println!("first")
    }
    if let Ordinals::Second = second {
        println!("second")
    }
    if four.is_fourth() {
        println!("fourth")
    }
}

fn match_option(opt: Option<i32>) -> String {
    match opt {
        Some(x) => format!("{}", x),
        None => "none".to_string(),
    }
}
